package com.mkb.service.impl;

import java.util.*;

import com.mkb.entity.*;
import com.mkb.enums.CaseColorEnum;
import com.mkb.enums.UserColorEnum;
import com.mkb.enums.UserOriginEnum;
import com.mkb.service.*;
import com.mkb.utils.MapUtils;
import com.zz.common.util.DateUtils;
import com.zz.common.util.ObjectUtils;
import com.zz.common.validator.Assert;
import com.zz.common.validator.ValidatorUtils;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mkb.dao.GraphDAO;
import org.springframework.transaction.annotation.Transactional;

@Service
public class GraphServiceImpl implements GraphService {
	@Autowired
	private GraphDAO graphDAO;
	@Autowired
	private AreaService areaService;
	@Autowired
	private GraphCaseService graphCaseService;
	@Autowired
	private GraphClueService graphClueService;
	@Autowired
	private GraphUserService graphUserService;
	@Autowired
	private GraphUserDetailService graphUserDetailService;
	@Autowired
	private UserDetailFamilyService userDetailFamilyService;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean deleteById(Long id) throws Exception{
		//如果有数据不让删除
		List<GraphCaseDTO> graphCaseDTOS = graphCaseService.queryList(GraphCaseDTO.builder().graphId(id).build());
		List<GraphClueDTO> graphCuleDTOS = graphClueService.queryList(GraphClueDTO.builder().graphId(id).build());
		List<GraphUserDTO> graphUserDTOS = graphUserService.queryList(GraphUserDTO.builder().graphId(id).build());
		if (CollectionUtils.isNotEmpty(graphCaseDTOS) || CollectionUtils.isNotEmpty(graphCuleDTOS) || CollectionUtils.isNotEmpty(graphUserDTOS) ){
			return false;
		}
		graphDAO.deleteById(id);
		return true;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Long create(GraphDTO record) throws Exception {
		GraphDO entity = record.clone(GraphDO.class);
		//
		List<AreaDTO> areaDTOS = areaService.queryList(AreaDTO.builder().name(record.getAreaName()).build());
		AreaDTO areaDTO = areaDTOS.get(0);
		entity.setAreaId(areaDTO.getId());
		graphDAO.insert(entity);
		return entity.getId();
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean updateAttr(GraphDTO graphDTO) throws Exception {
		//更新graph
		update(graphDTO);

		graphUserDetailService.deleteByGraphId(graphDTO.getId());
		//新增案件明细
		updateCase(graphDTO);
		//新增线索明细
		updateClue(graphDTO);
		//新增人员明细
		updateUser(graphDTO);

		return Boolean.TRUE;
	}

	private void updateUser(GraphDTO graphDTO) throws Exception{
		graphUserService.deleteByGraphId(graphDTO.getId());
		List<GraphUserDTO> graphUserList = graphDTO.getGraphUserList();
		if (CollectionUtils.isEmpty(graphUserList)){
			return;
		}
		graphUserService.createBatch(graphUserList);
	}

	private void updateClue(GraphDTO graphDTO) throws Exception{
		graphClueService.deleteByGraphId(graphDTO.getId());
		List<GraphClueDTO> graphClueList = graphDTO.getGraphClueList();
		if (CollectionUtils.isEmpty(graphClueList)){
			return;
		}
		for (GraphClueDTO graphClueDTO : graphClueList){
			Long clueId = graphClueService.create(graphClueDTO);

			List<GraphUserDetailDTO> graphUserDetailList = graphClueDTO.getGraphUserDetailList();

			for (GraphUserDetailDTO graphUserDetailDTO : graphUserDetailList){
				graphUserDetailDTO.setGraphId(graphDTO.getId());
				graphUserDetailDTO.setOrigin(UserOriginEnum.CLUE.getValue());
				graphUserDetailDTO.setRalateId(clueId);
				graphUserDetailService.create(graphUserDetailDTO);
			}
		}
	}

	private void updateCase(GraphDTO graphDTO) throws Exception {
		graphCaseService.deleteByGraphId(graphDTO.getId());
		userDetailFamilyService.deleteByGraphId(graphDTO.getId());
		List<GraphCaseDTO> graphCaseList = graphDTO.getGraphCaseList();
		if (CollectionUtils.isEmpty(graphCaseList)){
			return;
		}
		for (GraphCaseDTO graphCaseDTO : graphCaseList){
			//新增案件
			Long caseId = graphCaseService.create(graphCaseDTO);
			List<GraphUserDetailDTO> graphUserDetailList = graphCaseDTO.getGraphUserDetailList();
			for (GraphUserDetailDTO graphUserDetailDTO : graphUserDetailList){
				graphUserDetailDTO.setGraphId(graphDTO.getId());
				graphUserDetailDTO.setOrigin(UserOriginEnum.CASE.getValue());
				graphUserDetailDTO.setRalateId(caseId);
				Long detailId = graphUserDetailService.create(graphUserDetailDTO);

				List<UserDetailFamilyDTO> userDetailFamilyList = graphUserDetailDTO.getUserDetailFamilyList();
				if (CollectionUtils.isNotEmpty(userDetailFamilyList)){
					userDetailFamilyList.forEach(item->{
						item.setDetailId(detailId);
						item.setGraphId(graphDTO.getId());
					});
					userDetailFamilyService.createBatch(userDetailFamilyList);
				}
			}
		}
	}


	@Override
	public GraphDTO getById(Long id) throws Exception{
		Assert.isNull(id, "id 不能为空");
		GraphDO entity= graphDAO.getById(id);
		Assert.isNull(entity, "对象不存在");
		GraphDTO dto = entity.clone(GraphDTO.class);
		return dto;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean update(GraphDTO record) throws Exception {
		Assert.isNull(record, "对象不存在");
		Assert.isNull(record.getId(), "对象id不存在");
		GraphDO entity = record.clone(GraphDO.class);
		graphDAO.update(entity);
		return true;
	}

	@Override
	public PageInfo<GraphDTO> queryPage(GraphDTO graphDTO) throws Exception {
	        ValidatorUtils.validateProperty(graphDTO, "pageNum", "pageSize");
		PageHelper.startPage(graphDTO.getPageNum(), graphDTO.getPageSize());
		List<GraphDO> graphDOS = graphDAO.queryList(MapUtils.parseMap(graphDTO));
		List<GraphDTO> graphDTOList = ObjectUtils.convertList(graphDOS, GraphDTO.class);
		Map<String , Object> params = new HashMap<>();
		for (GraphDTO record : graphDTOList){
			params.put("graphId", record.getId());
			record.setCaseNum(graphCaseService.count(params));
			record.setClueNum(graphClueService.count(params));
			record.setUserNum(graphUserService.count(params));
			record.setCreateTimeStr(DateUtils.formatDate(record.getCreateTime().getTime(), DateUtils.DATE_FROMAT2));
		}
		return new PageInfo<>(graphDTOList);
	}

	@Override
	public List<GraphDTO> queryList(GraphDTO graphDTO) throws Exception {
		List<GraphDO> graphDOS = graphDAO.queryList(MapUtils.parseMap(graphDTO));
		List<GraphDTO> graphDTOList = ObjectUtils.convertList(graphDOS, GraphDTO.class);
		return graphDTOList;
	}

	@Override
	public GraphDTO getAttr(Long graphId) throws Exception {
		GraphDTO graphDTO = getById(graphId);

		List<GraphUserDTO> graphUserDTOS = graphUserService.queryList(GraphUserDTO.builder().graphId(graphId).build());
		graphDTO.setGraphUserList(graphUserDTOS);

		List<GraphClueDTO> graphClueDTOS = graphClueService.queryList(GraphClueDTO.builder().graphId(graphId).build());
		for (GraphClueDTO graphClueDTO : graphClueDTOS){
			List<GraphUserDetailDTO> graphUserDetailDTOS = graphUserDetailService.queryList(GraphUserDetailDTO.builder().origin(UserOriginEnum.CLUE.getValue())
					.ralateId(graphClueDTO.getId()).build());
			graphClueDTO.setGraphUserDetailList(graphUserDetailDTOS);
		}
		graphDTO.setGraphClueList(graphClueDTOS);

		List<GraphCaseDTO> caseDTOList = graphCaseService.queryList(GraphCaseDTO.builder().graphId(graphId).build());
		for (GraphCaseDTO graphCaseDTO : caseDTOList){
			List<GraphUserDetailDTO> graphUserDetailDTOS = graphUserDetailService.queryList(GraphUserDetailDTO.builder()
					.origin(UserOriginEnum.CASE.getValue()).ralateId(graphCaseDTO.getId()).build());
			for (GraphUserDetailDTO graphUserDetailDTO : graphUserDetailDTOS){
				List<UserDetailFamilyDTO> userDetailFamilyDTOS = userDetailFamilyService.queryList(UserDetailFamilyDTO.builder().detailId(graphUserDetailDTO.getId()).build());
				graphUserDetailDTO.setUserDetailFamilyList(userDetailFamilyDTOS);
			}
			graphCaseDTO.setGraphUserDetailList(graphUserDetailDTOS);
		}
		graphDTO.setGraphCaseList(caseDTOList);

		return graphDTO;
	}

	@Override
	public List<GraphDTO> queryFullList(GraphDTO build) throws Exception {
		List<GraphDTO> graphDTOS = graphDAO.queryFullList(MapUtils.parseMap(build));
		for (GraphDTO graphDTO : graphDTOS){
			graphDTO.setColor(UserColorEnum.getColorByCount(Optional.ofNullable(graphDTO).map(GraphDTO::getUserNum).orElse(0)).getColorCode());
			graphDTO.setFillOpacity(CaseColorEnum.getRangeForCount(Optional.ofNullable(graphDTO).map(GraphDTO::getCaseNum).orElse(0)).getFillOpacity());
			graphDTO.setFillColor(CaseColorEnum.getRangeForCount(Optional.ofNullable(graphDTO).map(GraphDTO::getCaseNum).orElse(0)).getColorCode());
		}
		return graphDTOS;
	}

	private List<GraphCaseDTO> initCaseNull(List<GraphCaseDTO> caseDTOList) {
		if (CollectionUtils.isEmpty(caseDTOList)){
			List<GraphCaseDTO> resultList = new ArrayList<>();
			List<GraphUserDetailDTO> graphUserDetailDTOS = new ArrayList<>();
			List<UserDetailFamilyDTO> detailFamilyList = new ArrayList<>();

			GraphUserDetailDTO detailDTO = GraphUserDetailDTO.builder().build();
			UserDetailFamilyDTO familyDTO = UserDetailFamilyDTO.builder().build();
			detailFamilyList.add(familyDTO);

			detailDTO.setUserDetailFamilyList(detailFamilyList);
			graphUserDetailDTOS.add(detailDTO);
			GraphCaseDTO build = GraphCaseDTO.builder().build();
			build.setGraphUserDetailList(graphUserDetailDTOS);
			resultList.add(build);
			return  resultList;
		}
		return caseDTOList;
	}

	private List<GraphUserDTO> initUserNull(List<GraphUserDTO> graphUserDTOS) {
		if (CollectionUtils.isEmpty(graphUserDTOS)){
			List<GraphUserDTO> resultList = new ArrayList<>();
			resultList.add(GraphUserDTO.builder().build());
			return resultList;
		}
		return graphUserDTOS;
	}

	private List<GraphClueDTO> initClueNull(List<GraphClueDTO> graphClueDTOS) {
		if (CollectionUtils.isEmpty(graphClueDTOS)){
			List<GraphClueDTO> resultList = new ArrayList<>();
			List<GraphUserDetailDTO> graphUserDetailDTOS = new ArrayList<>();
			graphUserDetailDTOS.add(GraphUserDetailDTO.builder().build());

			GraphClueDTO build = GraphClueDTO.builder().build();
			build.setGraphUserDetailList(graphUserDetailDTOS);
			resultList.add(build);

			return resultList;
		}
		return graphClueDTOS;
	}

}